#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "zsocket.h"
#include <errno.h>
#include <string.h>
#define TPORT 40001
#define TBACKLOG 20
#define BUFFER_SIZE 1024

int main()
{
    int listenfd = 0;
    int client1fd = 0;
    // sockaddr_un 在使用进程间通信时用到本地套接字时会用到
    struct sockaddr_in addrSockListen;
    struct sockaddr_in addrClient;
    socklen_t addrClient_len;
    //socklen_t addrSockListenLen;
    int bindr = 0;
    int listenr = 0;
    char buffer[BUFFER_SIZE] = {0};
    int trecvlen = 0;

    //1. 定义监听的socket文件描述符
    //IPPROTO_IP 位于netinet/in.h中
    //当第三个参数为0时，会自动选择type类型对应的默认协议
    //int listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    listenfd = socket(AF_INET, SOCK_STREAM, ZDEFAULT_PROTOCOL);
    if(listenfd == -1)
    {
        //socket函数失败时返回-1
        //输出错误提示
        fprintf(stderr, "err: %s\n", strerror(errno));
        return -1;
    }

    //2.bind
    bzero(&addrSockListen, sizeof(addrSockListen));
    addrSockListen.sin_family = AF_INET;
    addrSockListen.sin_port = htons(TPORT);
    addrSockListen.sin_addr.s_addr = htonl(INADDR_ANY);
    bindr = bind(listenfd, (const struct sockaddr *)&addrSockListen, sizeof(addrSockListen) );
    if(bindr == -1)
    {
        fprintf(stderr, "err: %s\n", strerror(errno));
        return -1;
    }

    //3.listen
    listenr = listen(listenfd, TBACKLOG);
    printf("port:%d\n", TPORT);
    if(listenr == -1)
    {
        fprintf(stderr, "err: %s\n", strerror(errno));
        return -1;
    }

    //4.accept
    bzero(&addrClient, sizeof(addrClient));
    addrClient_len = sizeof(addrClient);
    client1fd = accept(listenfd, (struct sockaddr *)&addrClient, &addrClient_len);
    if(client1fd == -1)
    {
        fprintf(stderr, "err: %s\n", strerror(errno));
        return -1;
    }

    //5.recv
    while(1)
    {
        bzero(buffer, sizeof(buffer));
        trecvlen = recv(client1fd, buffer, sizeof(buffer), 0);
        if(trecvlen == -1)
        {
            fprintf(stderr, "err: %s\n", strerror(errno));
            return -1;
        }
        if(strcmp(buffer, "quit") == 0)
        {
            break;
        }
        fputs(buffer, stdout);
        send(client1fd, buffer, trecvlen, 0);
    }

    printf("OK\n");
    getchar();
    return 0;
}
